//
//  ViewController.m
//  AESTest
//
//  Created by zmjios on 2016/10/25.
//  Copyright © 2016年 zmjios. All rights reserved.
//

#import "ViewController.h"
#import "NSData+CommonCrypto.h"
#import "AESCrypt.h"
#import "aes.h"
#import "NSString+Base64.h"
#import "NSData+AES.h"
#import "GTMBase64.h"

#import "AESUtil.h"

#import "daes.h"

//#include "ctrippaycodeencrypt.hpp"
//#include <stdlib.h>
//#include <sstream>

#import "CTPayEncriptyUtil.h"


//using namespace std;

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
//    NSString *number = @"12345678908790";
//    NSData *data1 = [number dataUsingEncoding:NSUTF8StringEncoding];
//    NSLog(@"data.bytes = %s",[data1 bytes]);
//    NSString *key = @"test";
//    NSData *encriptData = [data1 AES256EncryptedDataUsingKey:key error:nil];
//    NSString *encriptString = [[NSString alloc] initWithBytes:[encriptData bytes] length:[encriptData length] encoding:NSUTF8StringEncoding];
//    NSString *test = [NSString stringWithCString:[encriptData bytes] encoding:NSUTF8StringEncoding];
//    NSLog(@"💚💚💚💚💚encriptString = %@,encriptString.length = %ld💚💚💚💚💚",encriptString,[encriptString length]);
//    
//    NSData *entest1 = [data1 AES256EncryptWithKey:@"1234567890123456"];
//    NSData *detest1 = [entest1 AES256DecryptWithKey:@"1234567890123456"];
//
//    NSString *origin1 = [NSString stringWithCString:[detest1 bytes] encoding:NSUTF8StringEncoding];
//    
//    NSLog(@"origin1 = %@",origin1);
//    
//    
//    NSString *test2 = [AESUtil encryptAES:number key:@"1234567890123456"];
//    NSString *detest2 = [AESUtil decryptAES:test2 key:@"1234567890123456"];
//    
//    [self testAES];
    
    
    //[self testAesm];
    
    //[self testToBinary];
    
    [self testCustom];
    
    //[self randomCodeTest];
    
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


//- (void)testAES
//{
//    uint8_t i, r;
//    
//    /* 128 bit key = 16 bytes*/
//    uint8_t key[] = {
//        0x0f, 0x15, 0x71, 0xc9, 0x47, 0xd9, 0xe8, 0x59,
//        0x0c, 0xb7, 0xad, 0xd6, 0xaf, 0x7f, 0x67, 0x98};
//    
//    uint8_t plain[] = {
//        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
//        0x08, 0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
//    
//    uint8_t cipher[BLOCK_SIZE_BYTE];
//    
//    uint8_t roundkeys[ROUND_KEY_SIZE];
//    
//    printf("\n--------------------------------------------------------\n");
//    // key schedule
//    aes_key_schedule_128(key, roundkeys);
//    printf("Key:\n");
//    for ( r = 0; r <= ROUNDS; r++ ) {
//        for (i = 0; i < BLOCK_SIZE_BYTE; i++) {
//            printf("%2x ", roundkeys[r*BLOCK_SIZE_BYTE+i]);
//        }
//        printf("\n");
//    }
//    printf("\n\n");
//    
//    
//    // encryption
//    // cipher text should be: 0x ff  b 84 4a  8 53 bf 7c 69 34 ab 43 64 14 8f b9
//    aes_encrypt_128(roundkeys, plain, cipher);
//    printf("Cipher text:\n");
//    for (i = 0; i < BLOCK_SIZE_BYTE; i++) {
//        printf("%2x ", cipher[i]);
//    }
//    printf("\n\n");
//    
//    
//    // decryption
//    aes_decrypt_128(roundkeys, cipher, plain);
//    printf("Plain text:\n");
//    for (i = 0; i < BLOCK_SIZE_BYTE; i++) {
//        printf("%2x ", plain[i]);
//    }
//    printf("\n");
//
//}




//- (void)testAesm
//{
//    for (int p = 0; p < 1; p ++) {
//        
//        uint32_t i;
//        
//        /* 32 key */
//        uint32_t key[] = {2,2,2,4,5,6,7,8,9,0,
//                          9,8,7,6,5,4,3,2,1,0,
//                          1,2,3,4,5,6,7,8,9,0,1,2};
//        
//        uint32_t inNum[16] = {1,2,9,4,5,0,7,0,9,0,9,8,7,6,5,4};
//        
//        uint32_t outNum[16];
//        
//        uint32_t *w; // expanded key
//        
//        w = (uint32_t *)malloc(44*4*sizeof(uint32_t));
//        
//        key_expansion(key, w);
//        
//        printf("🍉w:\n");
//        
//        for (i = 0; i < 176; i++) {
//            printf("%x ",w[i]);
//            if ((i+1) % 32 == 0) {
//                printf("\n");
//            }
//        }
//
//        printf("============\n");
//        
//        printf("🐝inNum:\n");
//        
//        for (i = 0; i < 16; i++) {
//            printf("%x ",inNum[i]);
//        }
//        
//        printf("============\n");
//        
//        cipher(inNum, outNum, w);
//        
//        printf("🐷outNum:\n");
//        
//        for (i = 0; i < 16; i++) {
//            printf("%x ",outNum[i]);
//        }
//        printf("============\n");
//        
//        inv_cipher(outNum, inNum, w);
//        
//        printf("\n🐹originmsg:\n");
//        for (i = 0; i < 16; i++) {
//            
//            printf("%x ", inNum[i]);
//            
//        }
//        
//        printf("\n");
//        
//        free(w);
//    }
//
//}
//
//
//- (void)testMixcol
//{
//    uint32_t inNum[16] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
//    
//    mix_columns(inNum);
//    
//    for(int i = 0; i < 16; i ++)
//    {
//        if (i == 0) {
//            printf("\n💙");
//        }
//        printf("%d ",inNum[i]);
//    }
//    
//    inv_mix_columns(inNum);
//    
//    for(int i = 0; i < 16; i ++)
//    {
//        if (i == 0) {
//            printf("\n🍀");
//        }
//        printf("%d ",inNum[i]);
//    }
//}
//
//
//- (void)testShiftRows
//{
//    uint32_t inNum[16] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
//    
//    shift_rows(inNum);
//    
//    for(int i = 0; i < 16; i ++)
//    {
//        if (i == 0) {
//            printf("\n💙");
//        }
//        printf("%d ",inNum[i]);
//    }
//    
//    inv_shift_rows(inNum);
//    
//    for(int i = 0; i < 16; i ++)
//    {
//        if (i == 0) {
//            printf("\n🍀");
//        }
//        printf("%d ",inNum[i]);
//    }
//}
//
//
//- (void)testSubbytes
//{
//    uint32_t inNum[16] = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
//    
//    sub_bytes(inNum,16);
//    
//    for(int i = 0; i < 16; i ++)
//    {
//        if (i == 0) {
//            printf("\n💙");
//        }
//        printf("%d ",inNum[i]);
//    }
//    
//    inv_sub_bytes(inNum, 16);
//    
//    for(int i = 0; i < 16; i ++)
//    {
//        if (i == 0) {
//            printf("\n🍀");
//        }
//        printf("%d ",inNum[i]);
//    }
//}
//
//
//
//- (void)testControlKey
//{
//    uint32_t inNum[16] = {1,5,9 ,3, 2 ,6, 0 ,4 ,3 ,7, 1 ,5 ,4, 8 ,2 ,6};
//    
//    /* 32 key */
//    uint32_t key[] = {1,2,3,4,5,6,7,8,9,0,9,8,7,6,5,4,
//        3,2,1,0,1,2,3,4,5,6,7,8,9,0,1,2};
//    
//    control_round_key(inNum, key, 0, 16);
//    
//    for(int i = 0; i < 16; i ++)
//    {
//        if (i == 0) {
//            printf("\n💙");
//        }
//        printf("%d ",inNum[i]);
//    }
//    
//    inv_control_round_key(inNum, key, 0, 16);
//    
//    for(int i = 0; i < 16; i ++)
//    {
//        if (i == 0) {
//            printf("\n🍀");
//        }
//        printf("%d ",inNum[i]);
//    }
//    
//    
//    int test = -1 % 10;
//    printf("🐺test = %d",test);
//}

char* toBinary(long decimal) {
    // variables
    static char binary[1000];
    int k = 0, n = 0;
    int negative = 0;
    int remain;
    char temp[strlen(binary)];
    
    // take care of negative input
    if (decimal < 0) {
        decimal = -decimal;
        negative = 1;
    }
    
    while (decimal > 0) {
        remain = decimal % 2;
        decimal = decimal / 2;
        temp[k++] = remain + '0';
    }
    
    //using sign and magnitude
    
    if (negative)
        temp[k++] = '1';
    else
        temp[k++] = '0';
    
    // reverse the spelling
    while (k >= 0)
        binary[n++] = temp[--k];
    
    binary[n - 1] = 0;
    return binary;
}


char *decimal_to_binary(int n)
{
    if (n > 15) {
        return NULL;
    }
    int c, d, count;
    char *pointer;
    
    count = 0;
    pointer = (char*)malloc(4);
    
    if ( pointer == NULL)
        exit(EXIT_FAILURE);
    
    for ( c = 3 ; c >= 0 ; c-- )
    {
        d = n >> c;
        
        if ( d & 1 )
            *(pointer+count) = 1 + '0';
        else
            *(pointer+count) = 0 + '0';
        
        count++;
    }
    *(pointer+count) = '\0';
    
    return  pointer;
}


- (void)testToBinary
{
    int a = 0XA, b = 0xe;
    
    char *c1 = toBinary(a);
    char *c2 = toBinary(b);
    
    NSString *d1 = [[NSString alloc] initWithUTF8String:c1];
    NSString *d2 = [NSString stringWithUTF8String:c2];
    
    char *e1 = decimal_to_binary(a);
    char *e2 = decimal_to_binary(b);
    
    NSString *f1 = [NSString stringWithUTF8String:e1];
    NSString *f2 = [NSString stringWithUTF8String:e2];
    
    NSLog(@"🐬d1=%@,d2=%@,f1=%@,f2=%@",d1,d2,f1,f2);
    
    
//    char a[] = "100";
//    char b[] = "100";
//    char c[] = "ffff";
//    char d[] = "A";
//    printf("a = %ld\n", strtol(a, NULL, 10)); //100
//    printf("b = %ld\n", strtol(b, NULL, 2));    //4
//    printf("c = %ld\n", strtol(c, NULL, 16)); //65535
//    printf("d = %ld\n", strtol(d, NULL, 16));
}

//string mmitos(long i){
//    stringstream s;
//    s << i;
//    return s.str();
//}

- (void)testCustom
{
    
    /*
    //创建异步串行队列
    dispatch_queue_t queue = dispatch_queue_create("me.tutuge.test.gcd", DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(queue, ^{
        
        NSLog(@"this is a test 🐱currentThread = %@",[NSThread currentThread]);
    });
    
    
    dispatch_async(queue, ^{
        
        NSLog(@"===== 🎩currentThread = %@",[NSThread currentThread]);
    });
    
    //运行block3次
    dispatch_apply(3, queue, ^(size_t i) {
        NSLog(@"apply loop: %zu", i);
        
        NSLog(@"🐬currentThread = %@",[NSThread currentThread]);
    });
    
    NSLog(@"🌎mainThread = %@",[NSThread currentThread]);
    
    //打印信息
    NSLog(@"After apply");*/
    
    
    
    
    NSString *randomCode = @"871459275";
    
    NSString *tcTime = @"003113";
    
    NSString *password =  [CTPayEncriptyUtil encryptRandomCode:randomCode tcTime:tcTime];
    
    NSString *encrypt = [CTPayEncriptyUtil decryptPayCode:password];
    
    NSLog(@"😂password = %@,encrypt = %@",password,encrypt);
    
//    password = @"213505020103908507";
//    NSString *origin = [CTPayEncriptyUtil decryptPayCode:password];
//    NSString *tcdtime = [CTPayEncriptyUtil getTcdtime:password];
//    
//    NSLog(@"🐬passoword = %@,orgin = %@,tcd = %@\n",password,origin,tcdtime);
//    
//    
//    NSString *password2 = [CTPayEncriptyUtil encryptRandomCode:origin tcTime:tcdtime];
    
//    NSLog(@"😅password2 = %@",password2);
    
    
}

void encryptRandomCode(){
    // audesd = "9ec#Nz"
    
    wchar_t audesd[7] = { 0xF426, 0xF452, 0xF450, 0xF410, 0xF43B, 0xF467, 0xF3ED };
    
    for (unsigned int IGkTP = 0, GrzIm = 0; IGkTP < 7; IGkTP++)
    {
        
        GrzIm = audesd[IGkTP];
        
        GrzIm += 0x0C13;
        
        audesd[IGkTP] = GrzIm;
        
    }
    
    printf("%s", audesd);
}

- (void)randomCodeTest
{
    NSString *test = @"lyuectrip";
    char *ptr = malloc(sizeof(char *)*strlen(test.UTF8String));
    strcpy(ptr, test.UTF8String);
    for(unsigned int i = 0,j = 0; i < strlen(ptr); i ++){
        j = *(ptr + i);
        j += 0x0C13;
        *(ptr+i) = j;
        
    }
    
    NSString *temp = [NSString stringWithCString:ptr encoding:NSUTF8StringEncoding];
    NSLog(@"🌸result = %@🌸",temp);
    
    //还原字符串
    for(unsigned int i = 0,j = 0; i < strlen(ptr); i ++){
        j = *(ptr + i);
        j -= 0x0C13;
        *(ptr+i) = j;
    }
    
    NSString *result = [NSString stringWithCString:ptr encoding:NSUTF8StringEncoding];
    free(ptr);
    
    NSLog(@"😂result = %@😂",result);
}





@end
